{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Meshed AC-DC example\n",
    "\n",
    "This example has a 3-node AC network coupled via AC-DC converters to a 3-node DC network. There is also a single point-to-point DC using the Link component.\n",
    "\n",
    "The data files for this example are in the examples folder of the github repository: <https://github.com/PyPSA/PyPSA>."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "import pypsa\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import os\n",
    "import matplotlib.pyplot as plt\n",
    "import cartopy.crs as ccrs\n",
    "\n",
    "%matplotlib inline\n",
    "plt.rc(\"figure\", figsize=(8, 8))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network = pypsa.examples.ac_dc_meshed(from_master=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "# get current type (AC or DC) of the lines from the buses\n",
    "lines_current_type = network.lines.bus0.map(network.buses.carrier)\n",
    "lines_current_type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "network.plot(\n",
    "    line_colors=lines_current_type.map(lambda ct: \"r\" if ct == \"DC\" else \"b\"),\n",
    "    title=\"Mixed AC (blue) - DC (red) network - DC (cyan)\",\n",
    "    color_geomap=True,\n",
    "    jitter=0.3,\n",
    ")\n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "network.links.loc[\"Norwich Converter\", \"p_nom_extendable\"] = False"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We inspect the topology of the network. Therefore use the function `determine_network_topology` and inspect the subnetworks in `network.sub_networks`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.determine_network_topology()\n",
    "network.sub_networks[\"n_branches\"] = [\n",
    "    len(sn.branches()) for sn in network.sub_networks.obj\n",
    "]\n",
    "network.sub_networks[\"n_buses\"] = [len(sn.buses()) for sn in network.sub_networks.obj]\n",
    "\n",
    "network.sub_networks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The network covers 10 time steps. These are given by the `snapshots` attribute."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.snapshots"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are 6 generators in the network, 3 wind and 3 gas. All are attached to buses:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.generators"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We see that the generators have different capital and marginal costs. All of them have a `p_nom_extendable` set to `True`, meaning that capacities can be extended in the optimization.\n",
    "\n",
    "The wind generators have a per unit limit for each time step, given by the weather potentials at the site. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.generators_t.p_max_pu.plot.area(subplots=True)\n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alright now we know how the network looks like, where the generators and lines are. Now, let's perform a optimization of the operation and capacities."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "network.optimize();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The objective is given by:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.objective"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Why is this number negative? It considers the starting point of the optimization, thus the existent capacities given by `network.generators.p_nom` are taken into account.  \n",
    "\n",
    "The real system cost are given by"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.objective + network.objective_constant"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The optimal capacities are given by `p_nom_opt` for generators, links and storages and `s_nom_opt` for lines.\n",
    "\n",
    "Let's look how the optimal capacities for the generators look like."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.generators.p_nom_opt.div(1e3).plot.bar(ylabel=\"GW\", figsize=(8, 3))\n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Their production is again given as a time-series in `network.generators_t`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.generators_t.p.div(1e3).plot.area(subplots=True, ylabel=\"GW\")\n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What are the Locational Marginal Prices in the network. From the optimization these are given for each bus and snapshot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.buses_t.marginal_price.mean(1).plot.area(figsize=(8, 3), ylabel=\"Euro per MWh\")\n",
    "plt.tight_layout()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can inspect further quantities as the active power of AC-DC converters and HVDC link."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "network.links_t.p0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "network.lines_t.p0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "...or the active power injection per bus."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "jupyter": {
     "outputs_hidden": false
    },
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "network.buses_t.p"
   ]
  }
 ],
 "metadata": {
  "@webio": {
   "lastCommId": null,
   "lastKernelId": null
  },
  "kernelspec": {
   "display_name": "",
   "language": "python",
   "name": ""
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
